﻿#include<stdio.h>
#include<sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>

#include <unistd.h>
#include <pthread.h>
//#define Debug


typedef struct client_infor
{
	char id[3];
	int clnt_Fd;
}client_infor;
client_infor client_node[100];


void *first_thread(void *arg);
void *second_thread(void *arg);
void main()
{
	daemon(0, 0);
	#ifdef Debug
	printf("helloworld\r\n");
	#endif
	//建立一个socket套接字，第一个参数设置为地址簇为ipv4,第二个参数设置为数据流（tcp/ip协议ﺿ第三个参数是协议号，默认䶿
	int socketFd = socket(AF_INET, SOCK_STREAM, 0);
	#ifdef Debug
	printf("现在建立socket通信号是%d\r\n", socketFd);

	if (socketFd > 0)
	{
		printf("socket建立成功\r\n");
	}
	else
	{
		printf("socket通信失败\r\n");
	}
	#endif	


	//使用程序员定义的地址，包含两重结构体，并且对第一个成员其接收簇号设置为任意，第二个成员设置端口号，并且做网络地址转换,第三个是设置任意地址均可访问本服务器
	//使用新结构体必须增加头文乿include <arpa/inet.h>
	struct sockaddr_in server_msg;
	server_msg.sin_family = AF_INET;
	server_msg.sin_port = htons(8080);
	server_msg.sin_addr.s_addr = htonl(INADDR_ANY);

	//设置地址复用的选项值，非零表示为真
	int soc_opt = 1;
	//设置socket的地址复用，第一个是socket号，第二个是设置socket等级，第三个是地址复用选项，第四个是为真的指针，第五个是为真的数据大小
	setsockopt(socketFd, SOL_SOCKET, SO_REUSEADDR, &soc_opt, sizeof(soc_opt));

	//绑定socket号，第二个参数是设置的地址，要做强制类型转换和地址的数据大宿
	int bindRet = bind(socketFd, (struct sockaddr *)&server_msg, sizeof(server_msg));
	#ifdef Debug
	if (bindRet == 0)
	{
		printf("bind成功\r\n");
	}
	else
	{
		printf("bind失败\r\n");
	}
	#endif	
	int listenRet = listen(socketFd, 50);
	#ifdef Debug
	if (listenRet == 0)
	{
		printf("Listen成功\r\n");
	}
	else
	{
		printf("Listen失败\r\n");
	}
	#endif	


	pthread_t aa = 1;

	pthread_create(&aa, NULL, first_thread, (void *)&socketFd);
	while (1)
	{
	}
}

void *first_thread(void *arg)
{
	while (1)
	{
		int socketFd_F = *(int *)arg;
		#ifdef Debug
		printf("第一线程获得的socket号是%d\r\n", socketFd_F);
		#endif
		//定义客户端加入成功以后存储的地址变量
		struct sockaddr_in client_msg;
		//定义地址的长度变量，但不能用int，需要用新型的socklen_t?܌是避免不同系统的int长度不同而发明的一种新的数据类垿
		socklen_t len = sizeof(client_msg);
		//接收socket号中来自客户端的数据，其中第二个是做强制类型转换，方法同bind,最后一个是设置地址的长度的指针


		//开辟第二线程
		int accept_ret = accept(socketFd_F, (struct sockaddr *)&client_msg, &len);
		#ifdef Debug
		if (accept_ret < 0)
		{
			printf("accept失败\r\n");
		}
		else
		{
			printf("accept成功\r\n");
		}
		#endif		


		//接收到数据链路把客户机描述符在结构体数组中找一个非零的数存起来先



		pthread_t id = 0;

		pthread_create(&id, NULL, second_thread, (void *)&accept_ret);
	}
}


//void *(*start_routine) (void *)
void *second_thread(void *arg)
{
	int client_Fd = *(int *)arg;
	#ifdef Debug
	printf("得到主线程传递过来的数据是%d\r\n", client_Fd);
	printf("这是第二线程，运行正常\r\n");
	#endif
	while (1)
	{
		char rev_data[32];
		memset(rev_data, 0, sizeof(rev_data));

		int rev_data_ret = read(client_Fd, rev_data, sizeof(rev_data));
		if (rev_data_ret > 0)
		{

			#ifdef Debug
			printf("i have reve data %d\n", rev_data_ret);
			printf("the data is %s\n", rev_data);
			#endif
			int i;
			//处理id:xxx的编号数据
			if (strstr(rev_data, "id:") != NULL)
			{
				char id[3] = { 0 };
				strcpy(id, rev_data + 3);
				//保存wifi模块的client socket号
				if (id[2] == '1')
				{
					client_node[1].clnt_Fd = client_Fd;
					#ifdef Debug
					printf("write wifi client_Fd %d\n", client_Fd);
					#endif					
				}
				//保存手机的client socket号
				if (id[2] == '2')
				{
					client_node[2].clnt_Fd = client_Fd;
					#ifdef Debug
					printf("write mobile client_Fd %d\n", client_Fd);
					#endif	
				}


			}
				//写to的程序
			if (strstr(rev_data, "to:"))
			{
				//找出来to：内容之间的id的值
				char id[3] = { 0 };
				char *p = rev_data + 3;
				int i = 0;
				while (*p != ':')
				{
					id[i] = *p;
					p++;
					i++;
				}
				p++;
				//截取出内容出来，存放在msg数组上
				char msg[32] = { 0 };

				strcpy(msg, p);
				//发送数据给wifi模块
				if (id[2] == '1')
				{
					#ifdef Debug
					printf("write to wifi\n");
					#endif	
					int write_Ret = write(client_node[1].clnt_Fd, msg, strlen(msg) + 1);
					#ifdef Debug
					if (write_Ret > 0)
					{
						printf("数据发送成功\r\n");
					}
					#endif			

				}
				//发送数据给手机	
				if (id[2] == '2')
				{
					#ifdef Debug
					printf("write to mobile\n");
					#endif
					int write_Ret = write(client_node[2].clnt_Fd, msg, strlen(msg) + 1);
					#ifdef Debug
					if (write_Ret > 0)
					{
						printf("数据发送成功\r\n");
					}
					#endif			
				}
			}
		}
	}
}
